﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EZ_B;
using System.Collections;

namespace GeneralAdaptiveFramework
{
    public class EscapeAnalyze : PassiveComponent
    {
        readonly int MIN_SIZE = 20;
        readonly int MAX_SIZE = 120;
        readonly int X = 320, Y = 240;

        public EscapeAnalyze(string _name)
            : base(_name)
        {
            initPort();
        }

        /**
         * Init two Provide ports and two Require ports
         */
        private void initPort()
        {
            interfaceList = new ArrayList();

            ProvideInterface provider01 = new ProvideInterface("PAnalyze01", this);
            ProvideInterface provider02 = new ProvideInterface("PAnalyze02", this);
            RequireInterface require01 = new RequireInterface("RAnalyze01", this);
            RequireInterface require02 = new RequireInterface("RAnalyze02", this);

            interfaceList.Add(provider01);
            interfaceList.Add(provider02);
            interfaceList.Add(require01);
            interfaceList.Add(require02);
        }

        /**
         * Receive data
         */
        public override void receiveData(Object data)
        {
            // add data to buffer
            buffer.Add(data);

            // call execute
            execute();
        }

        /**
         * Collect the object location by ColorDetection
         */
        public override void execute()
        {
            string message = "";
            // get data from buffer
            if (buffer.Count > 0)
            {
                // the data is an ObjectLocation
                CollectInfo info = (CollectInfo)buffer[0];
                buffer.RemoveAt(0);

                ObjectInfo location = null;
                if (info != null)
                {
                    location = info.objectLocation;
#if DEBUG
                    Console.WriteLine("EscapeAnalyze: " + location.centerX);
#endif
                    // applying the size filter
                    if (location.height < MIN_SIZE && location.width < MIN_SIZE)
                    {
                        location = null;
                    }
                    
                    // applying square filter
                    if (location != null)
                        if (!((float)location.width / location.height > 0.3 &&
                            (float)location.width / location.height < 2))
                        {   
#if DEBUG
                            Console.WriteLine("Found object too small: " + location.width + " " + location.height);
#endif
                            location = null;
                        }
                }
#if DEBUG
                else 
                    Console.WriteLine("Object not found");
#endif
                // after filter,
                if (location != null)
                {
                    message = determineLocation(location);
                }
#if DEBUG
                else
                    Console.WriteLine("Found object didnt pass the filter");
#endif
                // null location, just return empty message
                if (location == null)
                    message = "EMPTY";

                // send message after execution
                transferData(message);
            }
        }

        /* 
         * Generate Drone location based on ObjectLocation value to control the Drone
         */
        public string determineLocation(ObjectInfo objectLocation)
        {
            string location = "";
            int x = objectLocation.centerX, y = objectLocation.centerY;
            if (objectLocation.height > MAX_SIZE || objectLocation.width > MAX_SIZE)
            {
                location = "CLOSE";
                return location;
            }

            // list of actions
            
            if (x < X / 3)
                location = location + "LEFT ";
            else if (x > 2 * X / 3)
                location = location + "RIGHT ";

            if (y < Y / 3)
                location = location + "UP ";
            else if (y > 2 * Y / 3)
                location = location + "DOWN ";


            if (location.Length == 0)
                location = "CENTER";
            return location;
        }
    }
}
